package config

import (
	"gitee.com/pearl-zz/go-manage-system-core/config/reader"
	"gitee.com/pearl-zz/go-manage-system-core/config/source"
	"gitee.com/pearl-zz/go-manage-system-core/config/source/file"
)

type Config interface {
	reader.Values                          // Values provide the reader.Values interface
	Init(opts ...Option) error             // Init the config
	Options() Options                      // Options in the config
	Load(source ...source.Source) error    // Load config sources
	Sync() error                           // Sync Force a source changeSet sync
	Watch(path ...string) (Watcher, error) // Watch a value for changes
	Close() error
}

type Watcher interface {
	Next() (reader.Value, error)
	Stop() error
}

type Entity interface {
	OnChange()
}

func NewConfig(opts ...Option) (Config, error) {
	return newConfig(opts...)
}

var (
	DefaultConfig Config
)

// Bytes return config as raw json
func Bytes() []byte {
	return DefaultConfig.Bytes()
}

func Map() map[string]interface{} {
	return DefaultConfig.Map()
}

func Get(path ...string) reader.Value {
	return DefaultConfig.Get(path...)
}

func Scan(v interface{}) error {
	return DefaultConfig.Scan(v)
}

func Load(source ...source.Source) error {
	return DefaultConfig.Load(source...)
}

func Sync() error {
	return DefaultConfig.Sync()
}

func Watch(path ...string) (Watcher, error) {
	return DefaultConfig.Watch(path...)
}

func LoadFile(path string) error {
	return Load(file.NewSource(file.WithPath(path)))
}
